#include "FileShare.h"

#include "OnlineUsers.h"

#include "util/util.h"
#include "util/definitions.h"
#include "util/Log.h"

#include "lib/LockFile.h"

#include <iostream>
#include <fstream>
#include <list>


FileShare::FileShare(int myID) {

	this->myUserID = myID;
}

FileShare::~FileShare() {}

int FileShare::shareFile(std::string &path) {

	Log::getInstance().log(myUserID , "compartir archivo: " + path);

	int pos = findMySharedFile(path, true);

	if ( pos >= 0)
	{
		/* we have already shared that file... so we uncheck the bitmap  */
		Bitmap deletedBitmap(myUserID);
		deletedBitmap.turnOffBit(pos);
	}
	else
	{
		/* open the file where my shared files are listed */

		LockFile shared( getPathSharedFiles(myUserID).c_str() );

		char delim = SHARED_FILE_DELIMITER;

		/* add file to the list */

		shared.tomarLock( lock_escritura );
		shared.append( path.c_str(), path.length() );
		shared.append( &delim , sizeof(delim));
		shared.liberarLock();
	}
	return 0;
}

int FileShare::unshareFile(std::string &path) {

	Log::getInstance().log(myUserID , "Descompartir archivo: " + path);

	/* find my file */

	int pos = findMySharedFile(path);

	if ( pos >= 0) {

		Bitmap deletedBitmap(myUserID);
		deletedBitmap.turnOnBit(pos);	/* stop sharing */
	}
	else
	{
		 std::clog<<"Error: No se esta compartiendo el archivo "<<path<<std::endl;
		return 1;
	}

	return 0;
}

int FileShare::readSharedFiles(LockFile &shared, SharedFileList &list, int userID, bool showAll)
{
	std::string file;
	char character = '\0';
	int read = 0;
	size_t pos = 0;

	Bitmap deletedBitmap(userID);

	/* search through the user's shared file list */

	shared.tomarLock(lock_lectura);

	shared.seek(0);

	do
	{
		read = shared.leer(&character,sizeof(character)); //WARNING... read line maybe??

		if ( character != SHARED_FILE_DELIMITER)
			file += character;
		else {
			if ( read > 0 )
			{
				if ( showAll )
				{
					list.pushBack(userID, file); /* add file to the list if we want to show all files*/
				}
				else if (! deletedBitmap.isBitOn(pos))
				{
					list.pushBack(userID, file); /* add file to the list if it's not marked as deleted*/
				}

				file.clear();
				pos++;
			}
		}

	}while(read > 0);

	shared.liberarLock();

	return 0;

}

int FileShare::getMySharedFiles(SharedFileList &list, bool showAll) {

	return getSharedFiles(myUserID, list, showAll);
}

int FileShare::getSharedFiles(int userID, SharedFileList &list, bool showAll) {

	 std::clog<<"ver archivos compartidos de "<<userID<<std::endl;

	int ret = 0;

	if ( userID > 0 ) {

		std::string name = getPathSharedFiles(userID);

		 std::clog<<"abriendo "<<name<<std::endl;

		LockFile shared(name.c_str());

		if (shared.is_open() && shared.size() > 0) {

			ret = readSharedFiles(shared,list,userID,showAll);
		}
	}
	else
	{
	 	std::clog<<"usuario "<< userID<< " invalido"<<std::endl;
	}

	return ret;
}

int FileShare::getAllSharedFiles(SharedFileList &list, bool ignoreMine) {

	std::list<int> users;

	OnlineUsers userManager;

	userManager.getOnlineUsers(users);

	/* ask for everyone's shared files */

	std::list<int>::iterator itUsers = users.begin();

	while (itUsers != users.end())
	{
		if ( ! (ignoreMine && myUserID == (*itUsers)) )
			getSharedFiles( *itUsers, list );

		itUsers ++;
	}

	return 0;
}

int FileShare::findMySharedFile(std::string &path, bool showAll)
{
	/* this can be optimized but it's ok for now */

	SharedFileList list;

	getMySharedFiles(list,showAll );

	size_t size = list.getSize();
	size_t pos = 0;
	bool found = false;

	while (pos < size && !found)
	{
		found = ( path == list.getFileName(pos) );
		pos++;
	}

	return (found) ? pos-1 : -1;
}


